package controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JTable;

import logic.CashDispenser;
import logic.Transaction;
import ui.ScreenWB;
import db.BankDatabase;
import ui.ViewBalance;

public class ATMApp {

	private ScreenWB screenWb;
	private boolean userAuthenticated;
	private int currentAccountNumber; // current user's account number
	private CashDispenser cashDispenser;
	private boolean authenticateUsers = true;
	private BankDatabase bankDatabase; // account information database
	private ViewBalance viewBalance;
	private Transaction currentTransaction;

	public ATMApp() {
		userAuthenticated = true;
		currentAccountNumber = 0;

		this.bankDatabase = new BankDatabase();
		this.viewBalance = new ViewBalance();

		screenWb = new ScreenWB();
		screenWb.getCustomerLogin().addActionListener(
				new CustomerLoginActionListener(this));
		screenWb.getCustomerMenu().addActionListener(
				new CustomerMenuActionListener(this));
		screenWb.getDepositFundsMenu().addActionListener(
				new DepositFundsActionListener(this));
		screenWb.getDepositFundsSpending().addActionListener(
				new DepositFundsSpendingActionListener(this));
		screenWb.getViewBalance().addActionListener(
				new ViewBalanceActionListener(this));
		screenWb.getWithdrawCash().addActionListener(
				new WithdrawCashActionListener(this));
		screenWb.getWithdrawCashMenu().addActionListener(
				new WithdrawCashMenuActionListener(this));


	}

	public void run() {
		screenWb.Show(ScreenWB.CUSTOMERLOGIN);
		screenWb.setVisible(true);
	}

	// Customer login (Listener)
	private class CustomerLoginActionListener implements ActionListener {
		private ATMApp atmApp;

		public CustomerLoginActionListener(ATMApp instance) {
			this.atmApp = instance;
		}

		public void actionPerformed(ActionEvent e) {

			this.atmApp.authenticateUser();

			if (e.getSource() == screenWb.getCustomerLogin().getBtnLogin()) {

				if (this.atmApp.isAuthed()) {
					screenWb.Show(ScreenWB.CUSTOMERMENU);
				} else {
					System.out.println("Wrong login or password");
				}

			}

		}

	}
	// Withdraw cash Menu (Listener)
	private class WithdrawCashMenuActionListener implements ActionListener {

		private ATMApp atmApp;

		public WithdrawCashMenuActionListener(ATMApp instance) {
			this.atmApp = instance;
		}

		public void actionPerformed(ActionEvent e) {
			
			
			if (e.getSource() == screenWb.getWithdrawCashMenu()
					.getBtnWithdrawCash()) {
				
				screenWb.Show(ScreenWB.WITHDRAWCASH);

			} else if (e.getSource() == screenWb.getWithdrawCashMenu()
					.getBtnReturn()) {
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			}

		}
	}

	// Customer Menu (Listener)
	private class CustomerMenuActionListener implements ActionListener {

		private ATMApp atmApp;

		public CustomerMenuActionListener(ATMApp instance) {
			this.atmApp = instance;
		}

		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == screenWb.getCustomerMenu().getBtnViewBalance()) {
				screenWb.getViewBalance().displayAccounts(
						this.atmApp.currentAccountNumber);
				screenWb.Show(ScreenWB.VIEWBALANCE);

			} else if (e.getSource() == screenWb.getCustomerMenu()
					.getBtnWithdrawCash()) {
				screenWb.getWithdrawCashMenu().displayAccounts(
						this.atmApp.currentAccountNumber);

				screenWb.Show(ScreenWB.WITHDRAWCASHMENU);

			} else if (e.getSource() == screenWb.getCustomerMenu()
					.getBtnDepositFunds()) {
				screenWb.getDepositFundsMenu().displayAccounts(
						this.atmApp.currentAccountNumber);
				screenWb.Show(ScreenWB.DEPOSITFUNDSMENU);

			} else if (e.getSource() == screenWb.getCustomerMenu()
					.getBtnLogout()) {
				this.atmApp.logOut();

				screenWb.getCustomerLogin().clearFields();

				screenWb.Show(ScreenWB.CUSTOMERLOGIN);

			}

		}
		

	}
	

	// Withdraw Cash (Listener)
	private class WithdrawCashActionListener implements ActionListener {

		private ATMApp atmApp;

		public WithdrawCashActionListener(ATMApp instance) {
			this.atmApp = instance;
		}

		public void actionPerformed(ActionEvent e) {	
			
			String id;
			id = screenWb.getWithdrawCashMenu().getAccountId();
				
			if (e.getSource() == screenWb.getWithdrawCash().getBtn$20()) {
				
				bankDatabase.WithdrawalCash(id, 20);				
				
				screenWb.showMessage("\nYour cash has been"
						+ " dispensed. Please take your cash now.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getWithdrawCash().getBtn$40()) {
				
				bankDatabase.WithdrawalCash(id, 40);
				
				screenWb.showMessage("\nYour cash has been"
						+ " dispensed. Please take your cash now.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getWithdrawCash().getBtn$60()) {
				
				bankDatabase.WithdrawalCash(id, 60);
				
				screenWb.showMessage("\nYour cash has been"
						+ " dispensed. Please take your cash now.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getWithdrawCash().getBtn$100()) {
				
				bankDatabase.WithdrawalCash(id, 100);
				
				screenWb.showMessage("\nYour cash has been"
						+ " dispensed. Please take your cash now.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getWithdrawCash().getBtn$200()) {
				
				bankDatabase.WithdrawalCash(id, 200);
				
				screenWb.showMessage("\nYour cash has been"
						+ " dispensed. Please take your cash now.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getWithdrawCash()
					.getBtnCancelTransaction()) {
				screenWb.showMessage("\nCanceling transaction...");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			}

		}

	}

	// View Balance (Listener)
	private class ViewBalanceActionListener implements ActionListener {

		private ATMApp atmApp;

		public ViewBalanceActionListener(ATMApp instance) {
			this.atmApp = instance;
		}

		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == screenWb.getViewBalance().getBtnReturn()) {

				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else
				screenWb.Show(ScreenWB.CUSTOMERMENU);
		}

	}

	// Deposit Funds Menu (Listener)
	private class DepositFundsActionListener implements ActionListener {

		private ATMApp atmApp;

		public DepositFundsActionListener(ATMApp instance) {
			this.atmApp = instance;
		}

		public void actionPerformed(ActionEvent e) {
			
			
			if (e.getSource() == screenWb.getDepositFundsMenu()
					.getBtnInsertCash()) {
				screenWb.Show(ScreenWB.DEPOSITFUNDSSPENDING);

			} else if (e.getSource() == screenWb.getDepositFundsMenu()
					.getBtnReturn()) {
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			}

		}
	}


	// Deposit Funds Spending (Listener)
	private class DepositFundsSpendingActionListener implements ActionListener {

		private ATMApp atmApp;

		public DepositFundsSpendingActionListener(ATMApp instance) {
			this.atmApp = instance;
		}

		public void actionPerformed(ActionEvent e) {
			String id = screenWb.getDepositFundsMenu().getAccountId();
			if (e.getSource() == screenWb.getDepositFundsSpending()
					.getBtnCancelTransaction()) {
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getDepositFundsSpending()
					.getBtn$5()) {
				
				bankDatabase.DepositCash(id, 5);
				
				screenWb.showMessage("\nYour envelope has been "
						+ "received.\nNOTE: The money just deposited will not "
						+ "be available until we verify the amount of any "
						+ "enclosed cash and your checks clear.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getDepositFundsSpending()
					.getBtn$10()) {
				
				bankDatabase.DepositCash(id, 10);
				
				screenWb.showMessage("\nYour envelope has been "
						+ "received.\nNOTE: The money just deposited will not "
						+ "be available until we verify the amount of any "
						+ "enclosed cash and your checks clear.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getDepositFundsSpending()
					.getBtn$20()) {
				
				bankDatabase.DepositCash(id, 20);
				
				screenWb.showMessage("\nYour envelope has been "
						+ "received.\nNOTE: The money just deposited will not "
						+ "be available until we verify the amount of any "
						+ "enclosed cash and your checks clear.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getDepositFundsSpending()
					.getBtn$50()) {
				
				bankDatabase.DepositCash(id, 50);
				
				screenWb.showMessage("\nYour envelope has been "
						+ "received.\nNOTE: The money just deposited will not "
						+ "be available until we verify the amount of any "
						+ "enclosed cash and your checks clear.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			} else if (e.getSource() == screenWb.getDepositFundsSpending()
					.getBtn$100()) {
				
				bankDatabase.DepositCash(id, 100);
				
				screenWb.showMessage("\nYour envelope has been "
						+ "received.\nNOTE: The money just deposited will not "
						+ "be available until we verify the amount of any "
						+ "enclosed cash and your checks clear.");
				screenWb.Show(ScreenWB.CUSTOMERMENU);

			}

		}
	}

	// attempts to authenticate user against database
	public void authenticateUser() {
		int loginId = 0;
		int password = 0;

		loginId = screenWb.getCustomerLogin().getLoginIdCustomer();
		password = screenWb.getCustomerLogin().getPasswordCustomer();

		System.out.println(loginId);
		System.out.println(password);

		System.out.println(this.bankDatabase);

		// set userAuthenticated to boolean value returned by database
		userAuthenticated = bankDatabase.authenticateUser(loginId, password);

		// check whether authentication succeeded
		if (userAuthenticated) {
			currentAccountNumber = loginId; // save user's account #
		} // end if
		else
			screenWb.showMessage("Invalid account number or PIN. Please try again.");
	} // end method authenticateUser

	public boolean isAuthed() {
		return this.userAuthenticated;
	}

	public void logOut() {
		this.userAuthenticated = false;

	}
}
